package com.qq.weixin.service;

import java.io.IOException;
import java.text.MessageFormat;

import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.qq.weixin.model.ResultInfo;
import com.qq.weixin.model.oauth.OAuthAccessToken;
import com.qq.weixin.model.oauth.OAuthUserInfo;

public class OAuthService {
  Logger logger = Logger.getLogger(OAuthService.class);
  private CloseableHttpClient httpclient = HttpClients.createDefault();
  private JsonParser parser = new JsonParser();

  public OAuthAccessToken getAccessToken(String appid, String secret, String code) {
    HttpGet getReq = new HttpGet(MessageFormat.format(
        "https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code", appid, secret,
        code));

    OAuthAccessToken accessToken = new OAuthAccessToken();
    CloseableHttpResponse getResp = null;
    try {
      getResp = httpclient.execute(getReq);
      String jsonstr = EntityUtils.toString(getResp.getEntity());
      JsonElement element = parser.parse(jsonstr);
      ResultInfo resultInfo = ResultInfo.convert(element);
      accessToken.setResultInfo(resultInfo);
      if (resultInfo.isSuccess()) {
        accessToken.setAccess_token(element.getAsJsonObject().get("access_token").getAsString());
        accessToken.setExpires_in(element.getAsJsonObject().get("expires_in").getAsLong());
        accessToken.setRefresh_token(element.getAsJsonObject().get("refresh_token").getAsString());
        accessToken.setOpenid(element.getAsJsonObject().get("openid").getAsString());
        accessToken.setScope(element.getAsJsonObject().get("scope").getAsString());
        if (element.getAsJsonObject().get("unionid") != null) {
          accessToken.setUnionid(element.getAsJsonObject().get("unionid").getAsString());
        }

      }
    } catch (Exception e) {
      logger.error("", e);
    } finally {
      if (getResp != null) {
        try {
          getResp.close();
        } catch (IOException e) {
          logger.error("", e);
        }
      }
    }

    return accessToken;
  }

  public OAuthAccessToken refreshToken(String appid, String refresh_token) {
    HttpGet getReq = new HttpGet(MessageFormat.format(
        "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid={0}&refresh_token={1}&grant_type=refresh_token", appid, refresh_token));

    OAuthAccessToken accessToken = new OAuthAccessToken();
    CloseableHttpResponse getResp = null;
    try {
      getResp = httpclient.execute(getReq);
      String jsonstr = EntityUtils.toString(getResp.getEntity());
      JsonElement element = parser.parse(jsonstr);
      ResultInfo resultInfo = ResultInfo.convert(element);
      accessToken.setResultInfo(resultInfo);
      if (resultInfo.isSuccess()) {
        accessToken.setAccess_token(element.getAsJsonObject().get("access_token").getAsString());
        accessToken.setExpires_in(element.getAsJsonObject().get("expires_in").getAsLong());
        accessToken.setRefresh_token(element.getAsJsonObject().get("refresh_token").getAsString());
        accessToken.setOpenid(element.getAsJsonObject().get("openid").getAsString());
        accessToken.setScope(element.getAsJsonObject().get("scope").getAsString());

      }
    } catch (Exception e) {
      logger.error("", e);
    } finally {
      if (getResp != null) {
        try {
          getResp.close();
        } catch (IOException e) {
          logger.error("", e);
        }
      }
    }

    return accessToken;
  }

  public OAuthUserInfo getUserInfo(String access_token, String openid) {
    HttpGet getReq = new HttpGet(MessageFormat.format("https://api.weixin.qq.com/sns/userinfo?access_token={0}&openid={1}&lang=zh_CN",
        access_token, openid));

    OAuthUserInfo userInfo = new OAuthUserInfo();
    CloseableHttpResponse getResp = null;
    try {
      getResp = httpclient.execute(getReq);
      String jsonstr = EntityUtils.toString(getResp.getEntity(), "utf-8");
      JsonElement element = parser.parse(jsonstr);
      ResultInfo resultInfo = ResultInfo.convert(element);
      userInfo.setResultInfo(resultInfo);
      if (resultInfo.isSuccess()) {
        userInfo.setOpenid(element.getAsJsonObject().get("openid").getAsString());
        if (element.getAsJsonObject().get("nickname") != null) {
          userInfo.setNickname(element.getAsJsonObject().get("nickname").toString().replace("\"", ""));
        }
        if (element.getAsJsonObject().get("sex") != null) {
          userInfo.setSex(element.getAsJsonObject().get("sex").getAsString());
        }
        if (element.getAsJsonObject().get("province") != null) {
          userInfo.setProvince(element.getAsJsonObject().get("province").getAsString());
        }
        if (element.getAsJsonObject().get("city") != null) {
          userInfo.setCity(element.getAsJsonObject().get("city").getAsString());
        }
        if (element.getAsJsonObject().get("country") != null) {
          userInfo.setCountry(element.getAsJsonObject().get("country").getAsString());
        }
        if (element.getAsJsonObject().get("headimgurl") != null) {
          userInfo.setHeadimgurl(element.getAsJsonObject().get("headimgurl").getAsString());
        }
        if (element.getAsJsonObject().get("privilege") != null) {
          userInfo.setPrivilege(element.getAsJsonObject().get("privilege").toString());
        }
        if (element.getAsJsonObject().get("unionid") != null) {
          userInfo.setUnionid(element.getAsJsonObject().get("unionid").getAsString());
        }

      }
    } catch (Exception e) {
      logger.error("", e);
    } finally {
      if (getResp != null) {
        try {
          getResp.close();
        } catch (IOException e) {
          logger.error("", e);
        }
      }
    }

    return userInfo;
  }

  public static void main(String[] args) {
    OAuthService service = new OAuthService();
    // OAuthAccessToken accessToken =
    // service.getAccessToken("wxf1af8f31d007525f",
    // "7607b9805c63ad5081ca5e01347ea9c7",
    // "001b9f19533db04e80b08d1ca005165F");
    // System.out.println(accessToken.getAccess_token() + "," +
    // accessToken.getOpenid() + "," + accessToken.getRefresh_token() + ","
    // + accessToken.getScope() + "," + accessToken.getUnionid() + "," +
    // accessToken.getExpires_in());
    // String str =
    // "OezXcEiiBSKSxW0eoylIeCKKkUf5OP0tuUqIZELF1PqZElYThvaXaDFUn1T9ayGGxlMEBTyH7rZVLsNJw8Or-vdHZdxgiD8NfAbK2KU_G5BrT_28fQ-TY0aM7sqF6unjxjfPOvJYdVxxmV8h6T1MVA,oo8uRuNO7LiwnH_GE_mGyhj8VqEo,OezXcEiiBSKSxW0eoylIeCKKkUf5OP0tuUqIZELF1PqZElYThvaXaDFUn1T9ayGGFkdG5IHyGdI6mjkG4TuObgUPOOlApl_4nOtfJK1i5sMf1c_i3ymTHV-wU3il52_d17jFD_EODp1Z52m8fDU0CQ,snsapi_userinfo,null,7200";
    // String refresh_token =
    // "OezXcEiiBSKSxW0eoylIeCKKkUf5OP0tuUqIZELF1PqZElYThvaXaDFUn1T9ayGGFkdG5IHyGdI6mjkG4TuObgUPOOlApl_4nOtfJK1i5sMf1c_i3ymTHV-wU3il52_d17jFD_EODp1Z52m8fDU0CQ";
    // OAuthAccessToken accessToken = service.refreshToken("wxf1af8f31d007525f",
    // refresh_token);
    // System.out.println(accessToken.getAccess_token() + "," +
    // accessToken.getOpenid() + "," + accessToken.getRefresh_token() + ","
    // + accessToken.getScope() + "," + accessToken.getUnionid() + "," +
    // accessToken.getExpires_in());
    // String str2 =
    // "OezXcEiiBSKSxW0eoylIeCKKkUf5OP0tuUqIZELF1PqZElYThvaXaDFUn1T9ayGGxlMEBTyH7rZVLsNJw8Or-vdHZdxgiD8NfAbK2KU_G5BrT_28fQ-TY0aM7sqF6unjxjfPOvJYdVxxmV8h6T1MVA,oo8uRuNO7LiwnH_GE_mGyhj8VqEo,OezXcEiiBSKSxW0eoylIeCKKkUf5OP0tuUqIZELF1PqZElYThvaXaDFUn1T9ayGGFkdG5IHyGdI6mjkG4TuObgUPOOlApl_4nOtfJK1i5sMf1c_i3ymTHV-wU3il52_d17jFD_EODp1Z52m8fDU0CQ,snsapi_base,snsapi_userinfo,,null,7200";
    //

    String access_toke = "OezXcEiiBSKSxW0eoylIeCKKkUf5OP0tuUqIZELF1PqZElYThvaXaDFUn1T9ayGGxlMEBTyH7rZVLsNJw8Or-vdHZdxgiD8NfAbK2KU_G5BrT_28fQ-TY0aM7sqF6unjxjfPOvJYdVxxmV8h6T1MVA";
    String openid = "oo8uRuNO7LiwnH_GE_mGyhj8VqEo";
    OAuthUserInfo userInfo = service.getUserInfo(access_toke, openid);
    Gson gson = new Gson();
    System.out.println(gson.toJson(userInfo));
  }

}
